package com.db.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;


public class ClientThread extends Thread {
    private Map<String, String> map;
    private Socket socket;
    int counter;
    private String lastMessage;
    private int ID;
    private boolean flag;
    private String lastMessageFromClient;
    private final static Logger logger = Logger.getLogger(ClientThread.class.getName());
	public ClientThread(Map<String, String> map, Socket socket, int ID) {
		this.map = map;
		this.socket = socket;
		this.counter = 0;
		this.ID = ID;
		this.flag = true;
	}
	public void run() {
		try {
			PrintWriter out = new PrintWriter(new OutputStreamWriter((socket.getOutputStream())), true);
			BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			sendMap(out, input);
			while (true) {
				Thread.sleep(10000);
				sendHeartBeat(out);
				if (lastMessageFromClient != null) {
					if (!(lastMessageFromClient.equals(lastMessage))) {
						sendUpdate(out, input);
					}
					logger.info("Client"+ID+" synchronized");
				}
				if (!(flag)) {
					sendUpdate(out, input);
					flag = true;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
		}
	}
	
	private void sendHeartBeat(PrintWriter out) {
		out.write(0+" "+'\n');
		out.flush();
		logger.info("Send heartBeat");
	}
	
	private void sendUpdate(PrintWriter out, BufferedReader input) throws IOException {
		logger.info("Send update");
		out.write("UpdateMap"+'\n');
		out.flush();
		sendMap(out, input);
	}
	
	public void setMap(Map<String, String> map) {
		this.map = map;
		this.flag = false;
	}
	
	private void sendMap(PrintWriter out, BufferedReader input) throws IOException {
		Iterator<Entry<String, String>> iter = map.entrySet().iterator();
		Entry<String, String> next;
		while (iter.hasNext()) {
			next = iter.next();
			counter++;
			out.write(next.getKey()+" "+next.getValue()+" "+counter+'\n');
			out.flush();
			lastMessage = ((Integer)counter).toString();
		}
		sendHeartBeat(out);
		lastMessageFromClient = input.readLine();
	}
}
